package iharbor2

import (
	"bytes"
	"context"
	"github.com/rclone/rclone/backend/iharbor2/api"
	"github.com/rclone/rclone/fs"
	"github.com/rclone/rclone/lib/rest"
	"io"
	"mime/multipart"
	"strconv"
)

// PUT
func (f *Fs) V1PutUploadBuffer(ctx context.Context, o *Object, in io.Reader, name string) (body *bytes.Buffer, contentType string, err error) {
	bodyBufOne := &bytes.Buffer{}
	bodyWriteOne := multipart.NewWriter(bodyBufOne)
	fileWrite, err := bodyWriteOne.CreateFormFile("file", name)
	if err != nil {
		fs.Debugf(o, "Update CreateFormFile : %v", err)
	}
	_, err = io.Copy(fileWrite, in)
	if err != nil {
		return nil, "", err
	}
	bodyWriteOne.Close() //要关闭，会将w.w.boundary刷写到w.writer中

	return bodyBufOne, bodyWriteOne.FormDataContentType(), err
}

func (f *Fs) V1FileUpload(ctx context.Context, o *Object, body *bytes.Buffer, contentType, md5String string) error {
	bucket, bucketPath := o.split()
	var opts rest.Opts
	Path := "/api/" + o.fs.opt.Version + "/obj/" + bucket + "/" + bucketPath + "/"

	ExtraHeaders := map[string]string{
		"Content-Type":   contentType,
		"Content-MD5":    md5String,
		"Content-Length": strconv.Itoa(body.Len()),
	}
	opts = f.HandlerAccesskeyHeader("PUT", Path, 3600, nil, nil, ExtraHeaders, body)

	//opts := rest.Opts{
	//	Method:  "PUT",
	//	RootURL: o.fs.opt.Endpoint + "/api/" + o.fs.opt.Version + "/obj/",
	//	Path:    bucket + "/" + bucketPath + "/",
	//	Body:    body,
	//	ExtraHeaders: map[string]string{
	//		"Content-Type":   contentType,
	//		"Content-MD5":    md5String,
	//		"Content-Length": strconv.Itoa(body.Len()),
	//	},
	//}

	var response api.FileInfo
	//// Don't retry, return a retry error instead
	err := o.fs.pacer.Call(func() (bool, error) {

		resp, err := o.fs.srv.CallJSON(ctx, &opts, nil, &response)
		retry, err := o.fs.shouldRetry(ctx, resp, err)
		//On retryable error clear UploadURL
		if retry {
			//fs.Debugf(o, "Clearing upload URL because of error: %v", err)
		}
		return retry, err
	})
	//if err != nil {
	//	fs.Debugf(o, "文件上传失败，请重试。")
	//	return err
	//}
	return err

}

func (f *Fs) V2FileUpload(ctx context.Context, o *Object, in io.Reader, md5Str string, lengsize int64) error {
	bucket, bucketPath := o.split()
	Path := "/api/" + f.opt.Version + "/obj/" + bucket + "/" + bucketPath
	ExtraHeaders := map[string]string{
		//"Authorization": "Token " + f.info.Token,
		"Content-MD5": md5Str,
	}
	opts := f.HandlerAccesskeyHeader("PUT", Path, 3600, nil, &lengsize, ExtraHeaders, in)
	//opts := rest.Opts{
	//	Method:  "PUT",
	//	RootURL: f.opt.Endpoint + "/api/" + f.opt.Version + "/obj/",
	//	Path:    bucket + "/" + bucketPath,
	//	Body:    in,
	//	ExtraHeaders: map[string]string{
	//		//"Authorization": "Token " + f.info.Token,
	//		"Content-MD5": md5Str,
	//	},
	//	ContentLength: &lengsize,
	//}
	var response api.UploadPartResponse
	//fmt.Printf("v2putmd5 %s \n", md5Str)

	err := o.fs.pacer.Call(func() (bool, error) {
		resp, err := f.srv.CallJSON(ctx, &opts, nil, &response)
		retry, err := f.shouldRetry(ctx, resp, err)
		if err != nil {
			fs.Debugf(o, "Error sending file (retry=%t): %d: %#v", retry, err)
		}
		// On retryable error clear PartUploadURL
		if retry {
			//fs.Debugf(o, "Clearing part upload URL because of error: %v", err)
			//return false, err
		}
		return retry, err
	})
	return err

}
